package com.tamir.template.express.handle;

import com.tamir.template.bean.LogicOperate;
import com.tamir.template.bean.TNode;
import com.tamir.template.context.TemplateContext;
import com.tamir.template.util.OperaterUtil;
import com.tamir.template.util.StringUtil;

import java.math.BigDecimal;

/**
 * @author : tanggh
 * @description :〈描述〉
 * @date : 2017/1/4
 */
public class DefaultLogicOperateValueHandle extends AbstractExpressValueHandle
{
    /**
     * 获取当前的值
     *
     * @param node
     * @param context
     * @return
     */
    @Override
    public Object getObject(TNode node, TemplateContext context) throws Exception
    {
        Object retValue = null;
        if(node != null && node.getLogicOperate() != null){
            retValue = this.getValue(node.getLogicOperate(), node, context);
        }
        return retValue;
    }

    @Override
    public String generateText(TNode node, TemplateContext context) throws Exception
    {
        StringBuffer textBuffer = new StringBuffer();
        if(node.gettLogicType() != null){
            textBuffer.append(this.getObject(node, context));
        }

        return textBuffer.toString();
    }

    /**
     * 获取值
     * @param operate   逻辑操作对象
     * @param node      父结点
     * @param context   模版上下文结点
     * @return
     */
    public Object getValue(LogicOperate operate, TNode node, TemplateContext context) throws
            Exception
    {
        Object retVal = null;
        if(operate != null){
            Object leftObj = null;
            Object rightObj = null;
            if(operate.getOperator() != null){
                leftObj = getValue(operate.getLeftOperate(), node, context);
                rightObj = getValue(operate.getRightOperate(), node, context);
                retVal = OperaterUtil.calObject(operate.getOperator(), leftObj, rightObj, node, operate);
            }else{
                String ex = operate.getExpress();
                if(StringUtil.isBoolean(ex)){
                    retVal = new Boolean(ex);
                }else if(StringUtil.isNumeric(ex)){
                    retVal = new BigDecimal(operate.getExpress());
                }else{
                    if(ex.charAt(0) == 39 && ex.charAt(ex.length() - 1) == 39){
                        return ex.substring(1, ex.length() - 1);
                    }
                    retVal = this.dealOperate(operate, node, context);
                }
            }
            if(operate.isNon()){
                if(retVal instanceof Boolean){
                    retVal = !(Boolean)retVal;
                }else{
                    retVal = !StringUtil.string2Boolean(retVal.toString());
                }
            }
        }
        return retVal;
    }

    /**
     * 处理表达式,获取当前的值
     *
     * @param operate
     * @param node
     * @param context
     * @return
     */
    public Object dealOperate(LogicOperate operate, TNode node, TemplateContext context) throws
            Exception
    {
        Object inputObj = getInputObject(operate, node, context);
        String ex = operate.getExpress().replaceAll("\\s+", "");
        String[] attributes = ex.split("\\.");
        Object obj = getObjectWithAttrsAndInputObj(attributes, inputObj, operate.getInputKey(),
                ex);

        return obj;
    }

    /**
     * 根据获取输入的值
     *
     * @param node
     * @param context
     * @return
     */
    public Object getInputObject(LogicOperate operate, TNode node, TemplateContext context)
    {
        Object val = null;
        if (operate != null &&  StringUtil.isNotEmpty(operate.getInputKey()) && node != null)
        {
            //如果表达式的inputKey和node结点的parent的结点的outKey相同
            //父结点的输出为当前的值
            if (node.parentNode != null && operate.getInputKey().equalsIgnoreCase(node.parentNode.getOutKey()))
            {
                val = node.parentNode.getOutValue();
            }
            else
            {
                val = context.getObject(operate.getInputKey());
            }
        }
        return val;
    }
}
